﻿using System.Net;

namespace JLMiddlewares
{
    /// <summary>
    /// 替换真实IP为代理后的IP
    /// </summary>
    public class RealIpMiddleware
    {
        private readonly RequestDelegate _next;

        public RealIpMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public Task Invoke(HttpContext context)
        {
            var headers = context.Request.Headers;

            if (headers.ContainsKey("X-Forwarded-For"))
            {
                try
                {
                    string _headerStr = string.Empty; 

                    string _ip = GetIP(_headerStr);

                    if (!string.IsNullOrEmpty(_ip))
                    {
                        context.Connection.RemoteIpAddress = System.Net.IPAddress.Parse(_ip);
                    }

                }
                catch
                {

                }
            }
            return _next(context);
        }

        /// <summary>
        /// 获取最后一个非内网IP，如果没有获取到外网IP则使用第一个IP
        /// </summary>
        /// <returns></returns>
        private string GetIP(string headerStr)
        {
            string[] _ipList = headerStr.Split(',', StringSplitOptions.RemoveEmptyEntries);
            if (_ipList.Length == 0)
            {
                return string.Empty;
            }

            if (_ipList.Length == 1)
            {
                return _ipList[0];
            }

            for (int i = _ipList.Length - 1; i >= 0; i--)
            {
                string _ip = _ipList[i].Trim();

                if (string.IsNullOrWhiteSpace(_ip))
                {
                    continue;
                } 

                if (_ip.Split(":", StringSplitOptions.None)?.Length > 2)
                {
                    _ip = ConvertIPv6ToIPv4(_ip)?.MapToIPv4().ToString();
                }
                else if (_ip.Split(":", StringSplitOptions.None)?.Length == 2)
                {
                    _ip = _ip.Substring(0, _ip.IndexOf(":"));
                } 

                if (!string.IsNullOrWhiteSpace(_ip) && _ip.IndexOf(".") > -1)
                {
                    if (IPAddress.TryParse(_ip, out IPAddress tempAddress))
                    {
                        return _ip;
                    }

                }
            }
            return string.Empty;
        }

        /// <summary>
        /// 将IPv6地址转换为IPv4地址
        /// </summary>
        /// <param name="ipv6Address">IPv6地址字符串</param>
        /// <returns></returns>
        public static IPAddress ConvertIPv6ToIPv4(string ipv6Address)
        {
            IPAddress ipv4Address = null;
            if (IPAddress.TryParse(ipv6Address, out IPAddress tempAddress))
            {
                if (tempAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                {
                    // 如果是IPv4地址，直接返回
                    ipv4Address = tempAddress;
                }
                else
                {
                    // 如果是IPv6地址，尝试转换为IPv4地址
                    var ipv4Bytes = tempAddress.GetAddressBytes();
                    // 假设IPv4地址在IPv6地址的最后4个字节
                    ipv4Address = new IPAddress(ipv4Bytes.Skip(ipv4Bytes.Length - 4).ToArray());
                }

            }

            return ipv4Address;
        }

        /// <summary>
        /// 判断是否为内网代理服务器IP
        /// </summary>
        /// <param name="ipv4Address">IP地址</param>
        /// <returns></returns>
        private bool IsPrivateNetwork(string ipv4Address)
        {
            if (IPAddress.TryParse(ipv4Address, out var ip))
            {
                byte[] ipBytes = ip.GetAddressBytes();
                if (ipBytes[0] == 10) return true;
                if (ipBytes[0] == 172 && ipBytes[1] >= 16 && ipBytes[1] <= 31) return true;
                if (ipBytes[0] == 192 && ipBytes[1] == 168) return true;
            }
            return false;
        }

    }
}
